/*
 * Copyright (c) 2008, 2016, OneAPM and/or its affiliates. All rights reserved.
 */
package me.yufan.chess.operation;

import me.yufan.chess.config.Options;
import org.newdawn.slick.util.Log;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.swing.*;
import java.awt.*;
import java.io.StringWriter;

/**
 * Title: ErrorHandler
 * Description: Error handler to log and display errors.
 *
 * @author Yufan
 * @version 1.0.0
 * @since 2016-01-26 19:48
 */
public final class ErrorHandler {

    private static final Logger LOGGER = LoggerFactory.getLogger(ErrorHandler.class);
    /**
     * Error popup title.
     */
    private static final String TITLE = "Error";

    /**
     * Error popup description text.
     */
    private static final String DESC = "Program has encountered an error.";

    /**
     * Text area for Exception.
     */
    private static final JTextArea TEXT_AREA = new JTextArea(7, 30);

    /**
     * Scroll pane holding JTextArea.
     */
    private static final JScrollPane SCROLL = new JScrollPane(TEXT_AREA);

    /**
     * Error popup objects.
     */
    private static final Object[] MESSAGE = {DESC, SCROLL};

    static {
        TEXT_AREA.setEditable(false);
        TEXT_AREA.setBackground(UIManager.getColor("Panel.background"));
        TEXT_AREA.setCursor(Cursor.getPredefinedCursor(Cursor.TEXT_CURSOR));
        TEXT_AREA.setTabSize(2);
        TEXT_AREA.setLineWrap(true);
        TEXT_AREA.setWrapStyleWord(true);
    }

    private ErrorHandler() {
        // This class should not be instantiated.
    }

    /**
     * Displays an error popup and logs the given error.
     *
     * @param error  a description of the error
     * @param e      the exception causing the error
     */
    public static void error(String error, Throwable e) {
        if (error == null && e == null) {
            return;
        }

        // log the error
        if (error == null) {
            LOGGER.error("", e);
        } else if (e == null) {
            Log.error(error);
        } else {
            Log.error(error, e);
        }

        // set the TEXT_AREA to the error MESSAGE
        TEXT_AREA.setText(null);
        if (error != null) {
            TEXT_AREA.append(error);
            TEXT_AREA.append("\n");
        }
        String trace;
        if (e != null) {
            StringWriter sw = new StringWriter();
            trace = sw.toString();
            TEXT_AREA.append(trace);
        }

        // display popup
        try {
            UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
            if (Desktop.isDesktopSupported()) {
                Desktop desktop = Desktop.getDesktop();
                if (desktop.isSupported(Desktop.Action.OPEN)) {
                    desktop.open(Options.LOG_FILE);
                }
            }
            JOptionPane.showMessageDialog(null, MESSAGE, TITLE, JOptionPane.ERROR_MESSAGE);
        } catch (Exception e1) {
            LOGGER.error("An error occurred in the crash popup.", e1);
        }
    }
}
